"""
DaoMath 可视化工具：阴阳态演化图
基于【LM-META-CORE｜先天法则四大必然共识-v1】

功能模块：
1. 太极阴阳 ±0 静态结构
2. 四象法则动态演化
3. 相干/退相干循环
4. 守恒归零边界
"""

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Circle, Wedge
from matplotlib.animation import FuncAnimation
from scipy.integrate import odeint
import seaborn as sns

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False

class YinYangEvolution:
    """阴阳态演化核心类"""
    
    def __init__(self, coherence_threshold=1.0):
        """
        初始化参数
        
        Args:
            coherence_threshold: 相干阈值（生存区间边界）
        """
        self.threshold = coherence_threshold
        self.history = {'yin': [], 'yang': [], 'time': []}
        
    # ============ 核心物理模型 ============
    
    def dynamics(self, state, t, coupling=0.5, decay=0.1):
        """
        阴阳态动力学方程（介观法则 ±）
        
        ∂ψ_yin/∂t = -α·ψ_yin + β·ψ_yang + noise
        ∂ψ_yang/∂t = β·ψ_yin - α·ψ_yang + noise
        
        Args:
            state: [yin, yang] 态矢量
            t: 时间
            coupling: 阴阳耦合强度 β
            decay: 退相干率 α
            
        Returns:
            [dyin/dt, dyang/dt]
        """
        yin, yang = state
        
        # 正反馈/负反馈机制
        dyin = -decay * yin + coupling * yang + 0.1 * np.sin(t)
        dyang = coupling * yin - decay * yang + 0.1 * np.cos(t)
        
        # 守恒约束：yin + yang = 0 (总和归零)
        total = yin + yang
        dyin -= 0.5 * total
        dyang -= 0.5 * total
        
        return [dyin, dyang]
    
    def check_annihilation(self, yin, yang):
        """
        检查是否触发守恒归零机制
        
        条件：|yin| > threshold OR |yang| > threshold
        """
        if abs(yin) > self.threshold or abs(yang) > self.threshold:
            return True, "退相干突破阈值 → 湮灭归元"
        return False, "相干均衡态"
    
    # ============ 可视化方法 ============
    
    def plot_taiji_static(self, ax=None):
        """
        绘制静态太极图（阴阳 ±0 本源结构）
        """
        if ax is None:
            fig, ax = plt.subplots(figsize=(8, 8))
        
        # 外圆（太极）
        circle = Circle((0, 0), 1, color='white', ec='black', linewidth=2)
        ax.add_patch(circle)
        
        # 阴阳 S 曲线分界
        theta = np.linspace(0, 2*np.pi, 1000)
        r = 0.5 * (1 + 0.3 * np.sin(2*theta))
        x = r * np.cos(theta)
        y = r * np.sin(theta)
        
        # 阳鱼（+0）
        yang_wedge = Wedge((0, 0), 1, 90, 270, color='white', ec='black')
        ax.add_patch(yang_wedge)
        
        # 阴鱼（-0）
        yin_wedge = Wedge((0, 0), 1, -90, 90, color='black')
        ax.add_patch(yin_wedge)
        
        # 阴阳鱼眼（互根互化）
        yang_eye = Circle((0, 0.5), 0.15, color='black')
        yin_eye = Circle((0, -0.5), 0.15, color='white', ec='black')
        ax.add_patch(yang_eye)
        ax.add_patch(yin_eye)
        
        # 标注
        ax.text(0, 0.7, '阳 +0\n绝对守恒', ha='center', fontsize=12, color='red')
        ax.text(0, -0.7, '阴 -0\n绝对均衡', ha='center', fontsize=12, color='blue')
        ax.text(0, -1.4, '总和 = 0（守恒归零）', ha='center', fontsize=10)
        
        ax.set_xlim(-1.5, 1.5)
        ax.set_ylim(-1.5, 1.5)
        ax.set_aspect('equal')
        ax.axis('off')
        ax.set_title('太极阴阳 ±0 本源结构', fontsize=16, pad=20)
        
        return ax
    
    def plot_four_象_fractal(self, ax=None):
        """
        绘制四象法则分形嵌套图
        (+) 微观 → (±) 介观 → (×) 宏观 → (÷) 周期
        """
        if ax is None:
            fig, ax = plt.subplots(figsize=(10, 10))
        
        # 四象象限
        labels = ['(+) 微观法则\n产生必然性', 
                  '(±) 介观法则\n生存必然性',
                  '(×) 宏观法则\n演化必然性', 
                  '(÷) 周期法则\n归零必然性']
        colors = ['#FF6B6B', '#4ECDC4', '#FFE66D', '#95E1D3']
        
        # 绘制象限
        for i, (label, color) in enumerate(zip(labels, colors)):
            angle = i * 90
            wedge = Wedge((0, 0), 1, angle, angle+90, 
                         color=color, alpha=0.3, ec='black')
            ax.add_patch(wedge)
            
            # 标注位置
            mid_angle = np.deg2rad(angle + 45)
            x = 0.6 * np.cos(mid_angle)
            y = 0.6 * np.sin(mid_angle)
            ax.text(x, y, label, ha='center', va='center', 
                   fontsize=10, weight='bold')
        
        # 分形嵌套圈
        for r in [0.3, 0.6, 0.9]:
            circle = Circle((0, 0), r, fill=False, 
                          ec='gray', linestyle='--', alpha=0.5)
            ax.add_patch(circle)
        
        # 中心太极
        self.plot_taiji_static(ax)
        
        ax.set_xlim(-1.2, 1.2)
        ax.set_ylim(-1.2, 1.2)
        ax.set_aspect('equal')
        ax.axis('off')
        ax.set_title('四象法则分形嵌套', fontsize=16, pad=20)
        
        return ax
    
    def plot_coherence_cycle(self, t_max=50, dt=0.1):
        """
        绘制相干/退相干循环演化图
        """
        # 数值求解动力学方程
        t = np.arange(0, t_max, dt)
        initial_state = [0.1, -0.1]  # 初始微扰
        solution = odeint(self.dynamics, initial_state, t)
        
        yin = solution[:, 0]
        yang = solution[:, 1]
        
        # 记录历史
        self.history['yin'] = yin
        self.history['yang'] = yang
        self.history['time'] = t
        
        # 创建子图
        fig, axes = plt.subplots(2, 2, figsize=(14, 10))
        
        # 1. 时间演化曲线
        axes[0, 0].plot(t, yin, label='阴态 ψ₋', color='blue', linewidth=2)
        axes[0, 0].plot(t, yang, label='阳态 ψ₊', color='red', linewidth=2)
        axes[0, 0].axhline(self.threshold, color='green', 
                          linestyle='--', label='阈值上限')
        axes[0, 0].axhline(-self.threshold, color='green', 
                          linestyle='--', label='阈值下限')
        axes[0, 0].set_xlabel('时间 t')
        axes[0, 0].set_ylabel('态振幅')
        axes[0, 0].legend()
        axes[0, 0].set_title('阴阳态时间演化')
        axes[0, 0].grid(alpha=0.3)
        
        # 2. 相空间轨迹
        axes[0, 1].plot(yin, yang, color='purple', linewidth=1.5, alpha=0.7)
        axes[0, 1].scatter(yin[0], yang[0], color='green', 
                          s=100, label='初态', zorder=5)
        axes[0, 1].scatter(yin[-1], yang[-1], color='red', 
                          s=100, label='终态', zorder=5)
        
        # 绘制生存区间（阈值边界）
        theta = np.linspace(0, 2*np.pi, 100)
        bound_x = self.threshold * np.cos(theta)
        bound_y = self.threshold * np.sin(theta)
        axes[0, 1].plot(bound_x, bound_y, 'g--', 
                       linewidth=2, label='生存阈值')
        
        axes[0, 1].set_xlabel('阴态 ψ₋')
        axes[0, 1].set_ylabel('阳态 ψ₊')
        axes[0, 1].legend()
        axes[0, 1].set_title('相空间轨迹（介观法则）')
        axes[0, 1].grid(alpha=0.3)
        axes[0, 1].set_aspect('equal')
        
        # 3. 守恒量检验
        total_energy = yin**2 + yang**2
        total_sum = yin + yang
        
        axes[1, 0].plot(t, total_energy, label='总能量 E', 
                       color='orange', linewidth=2)
        axes[1, 0].plot(t, total_sum, label='总和 Σ', 
                       color='cyan', linewidth=2)
        axes[1, 0].axhline(0, color='black', linestyle='-', alpha=0.3)
        axes[1, 0].set_xlabel('时间 t')
        axes[1, 0].set_ylabel('守恒量')
        axes[1, 0].legend()
        axes[1, 0].set_title('守恒律检验（总和归零）')
        axes[1, 0].grid(alpha=0.3)
        
        # 4. 熵增/熵减分析
        # 定义相对熵：S = -Σ p_i log(p_i)
        p_yin = np.abs(yin) / (np.abs(yin) + np.abs(yang) + 1e-10)
        p_yang = np.abs(yang) / (np.abs(yin) + np.abs(yang) + 1e-10)
        entropy = -(p_yin * np.log(p_yin + 1e-10) + 
                   p_yang * np.log(p_yang + 1e-10))
        
        axes[1, 1].plot(t, entropy, color='magenta', linewidth=2)
        axes[1, 1].set_xlabel('时间 t')
        axes[1, 1].set_ylabel('相对熵 S')
        axes[1, 1].set_title('熵演化（退相干指标）')
        axes[1, 1].grid(alpha=0.3)
        
        plt.tight_layout()
        return fig
    
    def animate_evolution(self, frames=200, interval=50):
        """
        创建动态演化动画
        """
        fig, ax = plt.subplots(figsize=(8, 8))
        
        # 初始化
        t_max = 20
        t = np.linspace(0, t_max, frames)
        initial_state = [0.2, -0.2]
        
        # 求解完整轨迹
        solution = odeint(self.dynamics, initial_state, t)
        yin_full = solution[:, 0]
        yang_full = solution[:, 1]
        
        # 绘制静态元素
        theta = np.linspace(0, 2*np.pi, 100)
        bound_x = self.threshold * np.cos(theta)
        bound_y = self.threshold * np.sin(theta)
        ax.plot(bound_x, bound_y, 'g--', linewidth=2, label='生存阈值')
        
        # 动态元素
        line, = ax.plot([], [], 'purple', linewidth=2, alpha=0.6, label='轨迹')
        point, = ax.plot([], [], 'ro', markersize=10, label='当前态')
        time_text = ax.text(0.02, 0.95, '', transform=ax.transAxes)
        
        def init():
            ax.set_xlim(-1.5, 1.5)
            ax.set_ylim(-1.5, 1.5)
            ax.set_xlabel('阴态 ψ₋')
            ax.set_ylabel('阳态 ψ₊')
            ax.set_title('阴阳态实时演化')
            ax.legend()
            ax.grid(alpha=0.3)
            ax.set_aspect('equal')
            return line, point, time_text
        
        def update(frame):
            # 更新轨迹
            line.set_data(yin_full[:frame], yang_full[:frame])
            
            # 更新当前点
            point.set_data([yin_full[frame]], [yang_full[frame]])
            
            # 检查湮灭
            annihilate, status = self.check_annihilation(
                yin_full[frame], yang_full[frame]
            )
            
            # 更新文本
            time_text.set_text(
                f't = {t[frame]:.2f}\n'
                f'ψ₋ = {yin_full[frame]:.3f}\n'
                f'ψ₊ = {yang_full[frame]:.3f}\n'
                f'状态: {status}'
            )
            
            # 湮灭时变红
            if annihilate:
                point.set_color('red')
                point.set_markersize(15)
            else:
                point.set_color('blue')
                point.set_markersize(10)
            
            return line, point, time_text
        
        anim = FuncAnimation(fig, update, frames=frames, 
                           init_func=init, interval=interval, 
                           blit=True, repeat=True)
        
        return anim

# ============ 使用示例 ============

def demo_all():
    """演示所有可视化功能"""
    evolution = YinYangEvolution(coherence_threshold=0.8)
    
    # 1. 静态太极图
    fig1 = plt.figure(figsize=(8, 8))
    ax1 = fig1.add_subplot(111)
    evolution.plot_taiji_static(ax1)
    plt.savefig('taiji_static.png', dpi=150, bbox_inches='tight')
    
    # 2. 四象分形图
    fig2 = plt.figure(figsize=(10, 10))
    ax2 = fig2.add_subplot(111)
    evolution.plot_four_象_fractal(ax2)
    plt.savefig('four_xiang_fractal.png', dpi=150, bbox_inches='tight')
    
    # 3. 相干循环演化
    fig3 = evolution.plot_coherence_cycle(t_max=30, dt=0.05)
    plt.savefig('coherence_cycle.png', dpi=150, bbox_inches='tight')
    
    # 4. 动画（需要在交互环境中运行）
    # anim = evolution.animate_evolution(frames=300, interval=30)
    # anim.save('yin_yang_evolution.gif', writer='pillow', fps=20)
    
    plt.show()

if __name__ == "__main__":
    demo_all()
